package aos.entity;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.Vector;

import aos.exception.AosException;
import aos.log.LogUtils;

public class RouteTable {

	private HashMap<Integer, String> id2Ip;

	// private HashMap<String, Integer> ip2Id;

	public RouteTable(String propertiesFile) throws AosException {
		id2Ip = new HashMap<Integer, String>();
		// ip2Id = new HashMap<String, Integer>();
		Properties properties = new Properties();
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(propertiesFile);
		} catch (FileNotFoundException e) {
			LogUtils.errorLog("file \"" + propertiesFile + "\" not found");
			LogUtils.errorLog(e.getMessage());
			throw new AosException(e.getMessage(), e);
		}
		LogUtils.runLog("propertiesFile open success");
		try {
			properties.load(fis);
		} catch (IOException e) {
			LogUtils.errorLog("propertiesFile \"" + propertiesFile
					+ "\" load failed");
			LogUtils.errorLog(e.getMessage());
			throw new AosException(e.getMessage(), e);
		}
		LogUtils.runLog("propertiesFile load success");
		for (Object key : properties.keySet()) {
			String domain = null, ipAddress = null;
			try {
				domain = (String) properties.get(key);
				ipAddress = InetAddress.getByName(domain).getHostAddress();
			} catch (UnknownHostException e) {
				LogUtils.errorLog("ip address resolves failed: " + domain);
				LogUtils.errorLog(e.getMessage());
				throw new AosException(e.getMessage(), e);
			}
			LogUtils.debugLog("ip address resolves success: " + domain + " -> "
					+ ipAddress);
			id2Ip.put(Integer.parseInt((String) key), ipAddress);
		}
		LogUtils.runLog("ip addresses resolve success");
	}

	public String getIpAddress(int nodeId) {
		return id2Ip.get(nodeId);
	}

	public int getNodeIdByIp(String ipAddress) throws AosException {
		for (Integer nodeId : id2Ip.keySet()) {
			if (id2Ip.get(nodeId).equals(ipAddress)) {
				return nodeId;
			}
		}
		throw new AosException("getNodeIdByIp failed: " + ipAddress);
	}

	public int getLocalNodeId() throws AosException {

		Vector<InetAddress> ips = new Vector<InetAddress>();

		Enumeration<NetworkInterface> netInterfaces = null;
		try {
			netInterfaces = NetworkInterface.getNetworkInterfaces();
			while (netInterfaces.hasMoreElements()) {
				NetworkInterface ni = netInterfaces.nextElement();
				Enumeration<InetAddress> ip = ni.getInetAddresses();
				while (ip.hasMoreElements()) {
					ips.add(ip.nextElement());
				}
			}
			String localHostIpList = "";
			for (InetAddress ip : ips) {
				localHostIpList += ip.getHostAddress() + "/";
			}
			LogUtils.debugLog("localHostIpList: " + localHostIpList);
		} catch (SocketException e) {
			LogUtils.errorLog(e.getMessage());
			throw new AosException(e.getMessage(), e);
		}
		LogUtils.runLog("InetAddress:getAllByName success");
		for (Integer id : id2Ip.keySet()) {
			for (InetAddress inet : ips) {
				if (inet.getHostAddress().equals(id2Ip.get(id))) {
					LogUtils.runLog("find localhost id success: " + id);
					return id;
				}
			}
		}
		LogUtils.runLog("find localhost id failed");
		throw new AosException("getLocalNodeId failed");
	}

}
